因為現在我們已經有一個可以正常接收資料、儲存紀錄、查詢歷史資料,甚至計算統計結果的 Spring Boot 後端。
目前完成的功能包括:
接下來終於可以開始思考:
要怎麼讓 Java 程式和生成式 AI 溝通?
今天先不急著寫串接程式,而是先理解生成式 AI API 的基本概念,以及最重要的 Prompt 設計。
今天的目標是:
了解 Java 如何透過 API 與生成式 AI 模型溝通,並學習設計適合智慧健康助理的 Prompt。
前面幾天,我們已經使用 Java 完成不少功能。
例如 BMI 計算:
double bmi = weight / (height * height);
以及飲水量統計:
double average = total / 7.0;
這些都有明確的計算公式。
只要輸入資料正確,Java 就可以按照規則得到結果。
但如果我們希望系統能夠把健康紀錄整理成一段自然的文字,就會遇到另一種需求。
例如目前的每日健康摘要 API 會回傳:
{
"date": "2026-10-17",
"water": {
"totalWater": 1500,
"unit": "ml",
"hasRecord": true
},
"sleep": {
"totalHours": 7.5,
"unit": "hours",
"hasRecord": true
}
}
對程式來說,這樣的 JSON 很方便處理。
但如果是一般使用者,可能更希望看到:
今天已記錄 1500 ml 的飲水量,
以及 7.5 小時的睡眠時間。
可以持續記錄,觀察一段時間內的生活習慣變化。
這就是生成式 AI 可以協助的地方。
它可以把原本比較制式的資料,整理成容易閱讀的自然語言。
不過要先釐清:
AI 不應該取代 Java 的數值計算,也不應該只憑簡單的紀錄就判斷使用者是否健康。
我們希望 AI 扮演的是:
健康紀錄整理助手
而不是:
醫師
生成式 AI(Generative AI)是一種可以根據輸入內容產生新內容的人工智慧技術。
常見的生成內容包括:
這次的智慧健康助理主要會使用:
文字生成能力。
例如使用者提供:
今天喝水 1500 ml,睡眠 7.5 小時。
我們可以請 AI 將資料整理成一段摘要。
例如:
今天已記錄 1500 ml 的飲水量,
睡眠紀錄為 7.5 小時。
這些資料可以作為日後觀察生活習慣的參考。
和傳統程式不同的是,生成式 AI 不一定只按照固定模板回覆。
它可以根據 Prompt 的內容,調整文字的語氣、格式和表達方式。
不過這也代表:
AI 產生的內容不一定完全正確。
所以在健康相關應用中,我們需要特別注意它的使用範圍。
大型語言模型的英文是:
Large Language Model
簡稱:
LLM
它是生成式 AI 中常見的一種模型。
例如我們熟悉的 ChatGPT,就是建立在大型語言模型相關技術之上的應用。
大型語言模型可以根據輸入文字,產生相應的文字回覆。
例如:
請幫我整理以下健康紀錄。
模型就可以根據提供的資料產生摘要。
不過這裡有一個容易搞混的地方。
ChatGPT 和 AI API 並不是完全相同的東西。
ChatGPT 是使用者可以直接操作的 AI 應用。
而 AI API 則是讓開發者可以透過程式,使用模型提供的功能。
也就是說,我們不需要每次都打開 ChatGPT 網頁,手動複製健康資料。
未來可以讓 Spring Boot 直接呼叫 AI API。
其實 API 這個概念,我們已經學了很多天。
之前建立的:
GET /health/water
就是一個 API。
使用者發送 HTTP Request,Spring Boot 就會處理請求,再回傳 Response。
例如:
使用者
↓
GET /health/water
↓
Spring Boot
↓
查詢資料庫
↓
回傳 JSON
而生成式 AI API 也是類似的概念。
差別在於:
這次我們的 Spring Boot 程式會變成 API 的呼叫者。
例如:
Spring Boot
↓
發送 HTTP Request
↓
AI API
↓
AI 模型產生文字
↓
回傳結果
↓
Spring Boot
也就是說,Spring Boot 不只可以提供 API 給別人使用,也可以主動呼叫其他服務提供的 API。
這是今天很重要的一個觀念。
先來看看我們目前的系統。
使用者
↓
Spring Boot
↓
Service
↓
Repository
↓
H2 Database
目前主要負責儲存、查詢與整理健康資料。
加入 AI 後,可以變成:
使用者
↓
Spring Boot Controller
↓
HealthSummaryService
↓
取得每日健康摘要
↓
AI Service
↓
呼叫生成式 AI API
↓
取得文字摘要
↓
回傳給使用者
這裡最重要的是:
AI 不需要直接連接我們的 H2 Database。
我們可以先讓 Java 整理資料,再把需要的內容提供給 AI。
例如:
{
"date": "2026-10-17",
"waterIntake": 1500,
"sleepHours": 7.5
}
然後要求 AI:
請根據提供的健康紀錄,
產生一段簡短的繁體中文摘要。
這樣就可以把 AI 的工作限制在文字整理。
接下來先認識呼叫生成式 AI API 時,通常會經過哪些步驟。
例如:
{
"waterIntake": 1500,
"sleepHours": 7.5
}
這些資料可以來自我們之前建立的:
GET /health/summary
例如:
請根據以下健康紀錄,
產生一段 100 字以內的繁體中文摘要。
飲水紀錄:1500 ml
睡眠紀錄:7.5 小時
請只描述提供的資料,
不要提供醫療診斷。
Java 會透過 HTTP,將請求傳送到 AI 服務。
通常需要提供:
API Endpoint
API Key
Model
Prompt
不同 AI 服務的 API 格式可能不同。
模型根據 Prompt 產生文字。
例如:
今天已記錄 1500 ml 的飲水量,
以及 7.5 小時的睡眠時間。
可以持續記錄每日生活習慣,
方便日後比較不同日期的變化。
最後再由 Spring Boot 將 AI 回覆整理成 JSON。
例如:
{
"date": "2026-10-17",
"summary": "今天已記錄 1500 ml 的飲水量,以及 7.5 小時的睡眠時間。可以持續記錄每日生活習慣,方便日後比較不同日期的變化。"
}
這樣就完成了一次基本的 AI API 呼叫流程。
目前這些都只是流程示意,還沒有實際呼叫模型。
終於來到今天另一個重要的主題:
Prompt!
Prompt 可以理解成我們提供給 AI 的指令或輸入內容。
例如:
幫我整理今天的健康紀錄。
這就是一個非常簡單的 Prompt。
不過如果只有這句話,AI 可能不知道:
所以 Prompt 的設計會直接影響輸出結果。
例如:
請根據以下資料,
用繁體中文產生一段 100 字以內的健康紀錄摘要。
飲水紀錄:1500 ml
睡眠紀錄:7.5 小時
請使用清楚、友善的語氣。
不要提供疾病診斷或治療建議。
這樣就比單純說「幫我整理」更明確。
我把今天學到的 Prompt 設計方式整理成五個部分。
| 項目 | 說明 | 範例 |
|---|---|---|
| 角色 | 希望 AI 扮演什麼角色 | 健康紀錄整理助手 |
| 任務 | 希望 AI 完成什麼工作 | 整理每日健康紀錄 |
| 資料 | 提供 AI 哪些資訊 | 飲水量、睡眠時數 |
| 格式 | 希望 AI 如何回覆 | 繁體中文、100 字內 |
| 限制 | 哪些事情不能做 | 不提供醫療診斷 |
例如:
你是一位健康紀錄整理助手。
請根據以下資料,
產生一段 100 字以內的繁體中文摘要。
日期:2026-10-17
飲水紀錄:1500 ml
睡眠紀錄:7.5 小時
請使用清楚、友善的語氣。
只能描述提供的紀錄,
不要自行補充不存在的數據,
也不要提供醫療診斷或治療建議。
這樣的 Prompt 就比較符合我們目前的專案需求。
在使用部分 AI API 時,可以將訊息分成不同角色。
今天先認識兩種常見的角色:
System
以及:
User
System Prompt 主要用來設定模型的角色、任務原則和回覆限制。
例如:
你是一位健康紀錄整理助手。
請使用繁體中文回答。
你的工作是根據提供的資料整理健康紀錄,
不提供醫療診斷或治療建議。
不得自行編造使用者沒有提供的數據。
這些規則通常由開發者設定。
User Prompt 則可以放入這次要處理的資料或問題。
例如:
請整理以下健康紀錄:
日期:2026-10-17
飲水紀錄:1500 ml
睡眠紀錄:7.5 小時
兩者搭配起來,就能讓模型知道:
應該遵守哪些原則
以及:
這次需要處理哪些資料
不過要注意,不同 AI API 對訊息角色的支援方式可能不同。
而且 System Prompt 也不是絕對可靠的安全防護。
即使設定了限制,仍然需要在程式端進行資料驗證、權限控管,以及必要的輸出檢查。
假設我們只提供:
今天喝水 1500 ml,睡眠 7.5 小時。
請給我健康建議。
這樣可能會產生一些問題。
因為 AI 並不知道:
使用者的年齡
身體狀況
活動量
環境條件
也不知道這些紀錄是否完整。
如果直接要求 AI 提供個人化健康建議,就可能讓回覆超出目前資料能支持的範圍。
所以我希望智慧健康助理先專注在:
整理紀錄
描述數據
提醒資料可能不完整
而不是:
判斷使用者是否健康
或是:
診斷疾病
這樣比較符合目前系統的能力。
在使用生成式 AI 時,還有一個經常被提到的問題:
Hallucination
中文通常稱為:
AI 幻覺。
簡單來說,就是 AI 可能產生看起來合理,但其實沒有根據或不正確的內容。
例如我們只提供:
飲水紀錄:1500 ml
睡眠紀錄:7.5 小時
但 AI 卻回覆:
你今天運動了 30 分鐘,
而且睡眠品質非常良好。
這就有問題了。
因為我們根本沒有提供運動資料,也沒有提供足以判斷睡眠品質的資訊。
所以在設計 Prompt 時,可以明確要求:
只能使用提供的資料。
以及:
如果資料不足,請直接說明資料不足。
不過這些指令只能降低風險,不能保證模型永遠不會出錯。
未來正式串接 AI 時,還是要檢查回傳內容。
這是我覺得今天最重要的觀念之一。
假設我們有最近七天的飲水紀錄:
1200
1500
1800
1400
1600
1700
1300
如果想計算平均值,我們其實已經會使用 Java:
double average = total / 7.0;
所以不需要請 AI 重新計算。
比較理想的流程是:
H2 Database
↓
Java 查詢資料
↓
Java 計算統計結果
↓
產生結構化 JSON
↓
AI 整理文字
例如 Java 先算出:
{
"averageWater": 1500,
"recordedDays": 7,
"periodDays": 7
}
再請 AI 產生:
最近七天都有留下飲水紀錄,
平均每日紀錄量為 1500 ml。
這樣 AI 就不需要重新做數值運算。
也比較容易確認回覆中的數字是否正確。
如果要透過 Java 呼叫外部 AI 服務,通常需要使用:
API Key
API Key 可以理解成一組用來驗證 API 呼叫身分的憑證。
它讓服務提供者知道是哪個專案或帳戶在發送請求。
例如:
Java 程式
↓
攜帶 API Key
↓
AI API
↓
驗證請求
↓
處理並回傳結果
不過 API Key 有一件事情非常重要:
不能隨便公開!
例如不應該直接把真正的 API Key 寫進:
String apiKey = "真正的金鑰";
更不應該將金鑰直接上傳到公開的 GitHub Repository。
因為如果別人取得金鑰,就可能使用你的 API 額度,甚至產生費用。
所以未來串接時,我們會優先使用環境變數保存金鑰。
例如:
OPENAI_API_KEY
這樣就不需要把金鑰直接寫在 Java 原始碼中。
這也是開始串接之前需要注意的事情。
很多生成式 AI API 都會依照使用量計費。
例如可能根據:
輸入 Token
以及:
輸出 Token
計算費用。
Token 可以簡單理解成模型處理文字時使用的基本單位。
它不一定等於一個中文字或一個英文單字。
實際計費方式會依照:
而有所不同。
所以之後正式測試 API 時,我們需要注意使用量與費用。
另外,使用 ChatGPT 網頁版或訂閱 ChatGPT 方案,也不代表 API 使用額度一定包含在內。
API 的計費和使用權限需要另外確認。
因為我們的專案和健康資料有關,所以這個問題特別重要。
目前的資料包含:
BMI
飲水紀錄
睡眠紀錄
雖然現在只是練習專案,但如果未來真的讓其他使用者使用,就需要考慮資料隱私。
例如:
是否真的需要把所有資料都傳給 AI?
假設我們只是要產生每日健康摘要。
其實可能只需要:
{
"waterIntake": 1500,
"sleepHours": 7.5
}
不一定需要傳送:
姓名
電話
地址
身分證字號
因此可以採用:
資料最小化原則。
也就是只提供完成任務所需要的資料。
此外,也要確認 AI 服務提供者的資料處理方式、保存政策,以及相關隱私設定。
如果未來涉及真實使用者的健康資訊,就不能只把它當成一般練習資料來處理。
今天最後一個練習,就是先替我們的智慧健康助理設計一份 Prompt。
這份 Prompt 之後可以作為串接 AI 時的基礎。
你是一位智慧健康紀錄整理助手。
請使用繁體中文回答,語氣清楚、友善且簡潔。
你的主要任務是根據系統提供的健康紀錄,
整理成容易閱讀的文字摘要。
請遵守以下原則:
1. 只能根據提供的資料描述紀錄。
2. 不得自行編造不存在的健康數據。
3. 如果資料不足,應明確說明。
4. 不提供疾病診斷或治療建議。
5. 不將單一飲水量或睡眠時數直接判定為健康或不健康。
6. 回覆以 100 字以內為原則。
請根據以下資料產生每日健康紀錄摘要。
日期:2026-10-17
飲水紀錄:
1500 ml
睡眠紀錄:
7.5 小時
請整理成一段自然、容易理解的繁體中文文字。
今天已記錄 1500 ml 的飲水量,
以及 7.5 小時的睡眠時間。
可以持續記錄每天的生活習慣,
方便日後觀察不同日期的變化。
這裡只是我們希望模型產生的回覆範例。
實際串接後,AI 產生的文字可能不同。
不過透過比較明確的 Prompt,可以讓回覆更接近我們想要的方向。
還記得 Day 20 的每日健康摘要嗎?
我們特別加入了:
hasRecord
用來判斷某一天是否有紀錄。
例如:
{
"date": "2026-10-17",
"water": {
"totalWater": 0,
"unit": "ml",
"hasRecord": false
},
"sleep": {
"totalHours": 7.5,
"unit": "hours",
"hasRecord": true
}
}
如果直接把:
飲水量:0 ml
提供給 AI,它可能誤以為使用者真的完全沒有喝水。
所以未來在建立 Prompt 時,應該先根據 hasRecord 整理資料。
例如:
日期:2026-10-17
飲水紀錄:當日尚無紀錄
睡眠紀錄:7.5 小時
並要求 AI:
沒有紀錄的項目,不要推測實際數值。
這樣就能降低誤解資料的風險。
也讓我們前面建立的 DTO 設計,在今天開始發揮作用。
看到這裡可能會覺得:
既然已經知道 AI API 的流程了,為什麼今天不直接開始寫程式?
其實我原本也很想直接試試看 XD
不過仔細想想,AI 串接和一般 API 還是有一些不同。
例如:
API Key 管理
請求格式
Token 與費用
Prompt 設計
資料隱私
錯誤處理
如果一開始沒有想清楚,後面可能會遇到不少問題。
所以今天先把基本概念整理好。
下一篇再正式使用 Java 呼叫 AI API。
今天終於正式進入生成式 AI 的部分!
雖然還沒有真正呼叫 AI 模型,但已經了解接下來需要使用的基本概念。
今天學到的重點包括:
目前整個專案的規劃也變得更清楚:
使用者
↓
Spring Boot
↓
取得健康紀錄
↓
Java 計算與整理資料
↓
建立 Prompt
↓
呼叫 AI API
↓
取得文字摘要
↓
回傳給使用者
今天最大的收穫是:
AI 不一定要負責所有事情。讓 Java 處理資料與計算,再讓 AI 協助整理文字,才能讓不同技術發揮各自的優勢。
而且在健康相關應用中,除了功能能不能完成,也需要考慮資料是否正確、回覆是否適當,以及使用者隱私是否受到保護。
這些都是正式加入 AI 前需要先想清楚的事情。
今天已經認識生成式 AI API 和 Prompt 的基本概念。
所以下一篇終於要正式開始串接了!
預計會學習:
讓我們的智慧健康助理,第一次真正透過 Java 和生成式 AI 模型溝通!